home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS 1.31 / antlr / bits.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-10  |  20.1 KB  |  823 lines  |  [TEXT/MPS ]

  1. /*
  2.  * bits.c -- manage creation and output of bit sets used by the parser.
  3.  *
  4.  * $Id: bits.c,v 1.14 1994/12/31 21:02:55 parrt Exp parrt $
  5.  * $Revision: 1.14 $
  6.  *
  7.  * SOFTWARE RIGHTS
  8.  *
  9.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  10.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  11.  * company may do whatever they wish with source code distributed with
  12.  * PCCTS or the code generated by PCCTS, including the incorporation of
  13.  * PCCTS, or its output, into commerical software.
  14.  * 
  15.  * We encourage users to develop software with PCCTS.  However, we do ask
  16.  * that credit is given to us for developing PCCTS.  By "credit",
  17.  * we mean that if you incorporate our source code into one of your
  18.  * programs (commercial product, research project, or otherwise) that you
  19.  * acknowledge this fact somewhere in the documentation, research report,
  20.  * etc...  If you like PCCTS and have developed a nice tool with the
  21.  * output, please mention that you developed it using PCCTS.  In
  22.  * addition, we ask that this header remain intact in our source code.
  23.  * As long as these guidelines are kept, we expect to continue enhancing
  24.  * this system and expect to make other tools available as they are
  25.  * completed.
  26.  *
  27.  * ANTLR 1.31
  28.  * Terence Parr
  29.  * Parr Research Corporation
  30.  * with Purdue University and AHPCRC, University of Minnesota
  31.  * 1989-1995
  32.  */
  33. #include <stdio.h>
  34. #include <ctype.h>
  35. #ifdef __cplusplus
  36. #ifndef __STDC__
  37. #define __STDC__
  38. #endif
  39. #endif
  40. #include "set.h"
  41. #include "syn.h"
  42. #include "hash.h"
  43. #include "generic.h"
  44. #include "dlgdef.h"
  45.  
  46. /* char is only thing that is pretty much always known == 8 bits
  47.  * This allows output of antlr (set stuff, anyway) to be androgynous (portable)
  48.  */
  49. typedef unsigned char SetWordType;
  50. #define BitsPerByte        8
  51. #define BitsPerWord        BitsPerByte*sizeof(SetWordType)
  52.  
  53. static SetWordType *setwd = NULL;
  54. int setnum = -1;
  55. int wordnum = 0;
  56.  
  57. int esetnum = 0;
  58.  
  59. /* Used to convert native wordsize, which ANTLR uses (via set.c) to manipulate sets,
  60.    to bytes that are most portable size-wise.
  61.    */
  62. void
  63. #ifdef __STDC__
  64. DumpIntAsChars( FILE *f, char *format, unsigned wd )
  65. #else
  66. DumpIntAsChars( f, format, wd )
  67. FILE *f;
  68. char *format;
  69. unsigned wd;
  70. #endif
  71. {
  72.     int i;
  73.     /* uses max of 32 bit unsigned integer for the moment */
  74.     static unsigned long byte_mask[sizeof(unsigned long)] =
  75.                 { 0xFF, 0xFF00, 0xFF0000, 0xFF000000 };
  76. /*                  0xFF00000000, 0xFF0000000000, 0xFF000000000000, 0xFF00000000000000 };*/
  77.  
  78.     /* for each byte in the word */
  79.     for (i=0; i<sizeof(unsigned); i++)
  80.     {
  81.         /* mask out the ith byte and shift down to the first 8 bits */
  82.         fprintf(f, format, (wd&byte_mask[i])>>(i*BitsPerByte));
  83.         if ( i<sizeof(unsigned)-1) fprintf(f, ",");
  84.     }
  85. }
  86.  
  87. /* Create a new setwd (ignoring [Ep] token on end) */
  88. void
  89. #ifdef __STDC__
  90. NewSetWd( void )
  91. #else
  92. NewSetWd( )
  93. #endif
  94. {
  95.     SetWordType *p;
  96.  
  97.     if ( setwd == NULL )
  98.     {
  99.         setwd = (SetWordType *) calloc(TokenNum, sizeof(SetWordType));
  100.         require(setwd!=NULL, "NewSetWd: cannot alloc set wd\n");
  101.     }
  102.     for (p = setwd; p<&(setwd[TokenNum]); p++)  {*p=0;}
  103.     wordnum++;
  104. }
  105.  
  106. void
  107. #ifdef __STDC__
  108. DumpSetWd( void )
  109. #else
  110. DumpSetWd( )
  111. #endif
  112. {
  113.     if ( GenCC ) DumpSetWdForCC();
  114.     else DumpSetWdForC();
  115. }
  116.  
  117. /* Dump the current setwd to ErrFile. 0..MaxTokenVal */
  118. void
  119. #ifdef __STDC__
  120. DumpSetWdForC( void )
  121. #else
  122. DumpSetWdForC( )
  123. #endif
  124. {
  125.     int i,c=1;
  126.  
  127.     if ( setwd==NULL ) return;
  128.     if ( !GenCC ) fprintf(DefFile, "extern SetWordType setwd%d[];\n", wordnum);
  129.     fprintf(ErrFile,
  130.             "SetWordType setwd%d[%d] = {", wordnum, TokenNum-1);
  131.     for (i=0; i<TokenNum-1; i++)
  132.     {
  133.         DAWDLE;
  134.         if ( i!=0 ) fprintf(ErrFile, ",");
  135.         if ( c == 8 ) {fprintf(ErrFile, "\n\t"); c=1;} else c++;
  136.         fprintf(ErrFile, "0x%x", setwd[i]);
  137.     }
  138.     fprintf(ErrFile, "};\n");
  139. }
  140.  
  141. /* Dump the current setwd to Parser.C file. 0..MaxTokenVal;
  142.  * Only used if -CC on.
  143.  */
  144. void
  145. #ifdef __STDC__
  146. DumpSetWdForCC( void )
  147. #else
  148. DumpSetWdForCC( )
  149. #endif
  150. {
  151.     int i,c=1;
  152.  
  153.     if ( setwd==NULL ) return;
  154.     fprintf(Parser_h, "\tstatic SetWordType setwd%d[%d];\n", wordnum, TokenNum-1);
  155.     fprintf(Parser_c,
  156.             "SetWordType %s::setwd%d[%d] = {", CurrentClassName, wordnum,
  157.             TokenNum-1);
  158.     for (i=0; i<TokenNum-1; i++)
  159.     {
  160.         DAWDLE;
  161.         if ( i!=0 ) fprintf(Parser_c, ",");
  162.         if ( c == 8 ) {fprintf(Parser_c, "\n\t"); c=1;} else c++;
  163.         fprintf(Parser_c, "0x%x", setwd[i]);
  164.     }
  165.     fprintf(Parser_c, "};\n");
  166. }
  167.  
  168. /* Make a new set.  Dump old setwd and create new setwd if current setwd is full */
  169. void
  170. #ifdef __STDC__
  171. NewSet( void )
  172. #else
  173. NewSet( )
  174. #endif
  175. {
  176.     setnum++;
  177.     if ( setnum==BitsPerWord )        /* is current setwd full? */
  178.     {
  179.         DumpSetWd(); NewSetWd(); setnum = 0;
  180.     }
  181. }
  182.  
  183. /* s is a set of tokens.  Turn on bit at each token position in set 'setnum' */
  184. void
  185. #ifdef __STDC__
  186. FillSet( set s )
  187. #else
  188. FillSet( s )
  189. set s;
  190. #endif
  191. {
  192.     SetWordType mask=(((unsigned)1)<<setnum);
  193.     unsigned int e;
  194.  
  195.     while ( !set_nil(s) )
  196.     {
  197.         e = set_int(s);
  198.         set_rm(e, s);
  199.         setwd[e] |= mask;
  200.     }
  201. }
  202.  
  203.                     /* E r r o r  C l a s s  S t u f f */
  204.  
  205. /* compute the FIRST of a rule for the error class stuff */
  206. static set
  207. #ifdef __STDC__
  208. Efirst( char *rule, ECnode *eclass )
  209. #else
  210. Efirst( rule, eclass )
  211. char *rule;
  212. ECnode *eclass;
  213. #endif
  214. {
  215.     set rk, a;
  216.     Junction *r;
  217.     RuleEntry *q = (RuleEntry *) hash_get(Rname, rule);
  218.  
  219.     if ( q == NULL )
  220.     {
  221.         warnNoFL(eMsg2("undefined rule '%s' referenced in errclass '%s'; ignored",
  222.                         rule, TokenString(eclass->tok)));
  223.         return empty;
  224.     }
  225.     r = RulePtr[q->rulenum];
  226.     r->end->halt = TRUE;        /* don't let reach fall off end of rule here */
  227.     rk = empty;
  228.     REACH(r, 1, &rk, a);
  229.     r->end->halt = FALSE;
  230.     return a;
  231. }
  232.  
  233. /*
  234.  * scan the list of tokens/eclasses/nonterminals filling the new eclass
  235.  * with the set described by the list.  Note that an eclass can be
  236.  * quoted to allow spaces etc... However, an eclass must not conflict
  237.  * with a reg expr found elsewhere.  The reg expr will be taken over
  238.  * the eclass name.
  239.  */
  240. static void
  241. #ifdef __STDC__
  242. doEclass( char *eclass )
  243. #else
  244. doEclass( eclass )
  245. char *eclass;
  246. #endif
  247. {
  248.     TermEntry *q;
  249.     ECnode *p;
  250.     ListNode *e;
  251.     unsigned int t;
  252.     unsigned deg=0;
  253.     set a;
  254.     require(eclass!=NULL, "doEclass: NULL eset");
  255.     
  256.     p = (ECnode *) eclass;
  257.     lexmode(p->lexclass);    /* switch to lexclass where errclass is defined */
  258.     p->eset = empty;
  259.     for (e = (p->elist)->next; e!=NULL; e=e->next)
  260.     {
  261.         if ( islower( *((char *)e->elem) ) )    /* is it a rule ref? (alias FIRST request) */
  262.         {
  263.             a = Efirst((char *)e->elem, p);
  264.             set_orin(&p->eset, a);
  265.             deg += set_deg(a);
  266.             set_free( a );
  267.             continue;
  268.         }
  269.         else if ( *((char *)e->elem)=='"' )
  270.         {
  271.             t = 0;
  272.             q = (TermEntry *) hash_get(Texpr, (char *) e->elem);
  273.             if ( q == NULL )
  274.             {
  275.                 /* if quoted and not an expr look for eclass name */
  276.                 q = (TermEntry *) hash_get(Tname, *((char **)&(e->elem))=StripQuotes((char *)e->elem));
  277.                 if ( q != NULL ) t = q->token;
  278.             }
  279.             else t = q->token;
  280.         }
  281.         else    /* labelled token/eclass/tokclass */
  282.         {
  283.             q = (TermEntry *) hash_get(Tname, (char *)e->elem);
  284.             if ( q != NULL )
  285.             {
  286.                 if ( strcmp((char *)e->elem, TokenString(p->tok))==0 )
  287.                 {
  288.                     warnNoFL(eMsg1("self-referential error class '%s'; ignored",
  289.                                    (char *)e->elem));
  290.                     continue;
  291.                 }
  292.                 else
  293.                     t = q->token;
  294.             }
  295.             else t=0;
  296.         }
  297.         if ( t!=0 )
  298.         {
  299.             set_orel(t, &p->eset);
  300.             deg++;
  301.         }
  302.         else warnNoFL(eMsg2("undefined token '%s' referenced in errclass '%s'; ignored",
  303.                             (char *)e->elem, TokenString(p->tok)));
  304.     }
  305.     p->setdeg = deg;
  306. }
  307.  
  308. void
  309. #ifdef __STDC__
  310. ComputeErrorSets( void )
  311. #else
  312. ComputeErrorSets( )
  313. #endif
  314. {
  315. #ifdef __cplusplus
  316.     list_apply(eclasses, (void (*)(void *)) doEclass);
  317. #else
  318. #ifdef __STDC__
  319.     list_apply(eclasses, (void (*)(void *)) doEclass);
  320. #else
  321.     list_apply(eclasses, doEclass);
  322. #endif
  323. #endif
  324. }
  325.  
  326. void
  327. #ifdef __STDC__
  328. ComputeTokSets( void )
  329. #else
  330. ComputeTokSets( )
  331. #endif
  332. {
  333.     ListNode *t, *e = NULL;
  334.     int something_changed;
  335.     TCnode *p;
  336.     TermEntry *q;
  337.  
  338.     if ( tclasses == NULL ) return;
  339.  
  340.     /* turn lists of token/tokclass references into sets */
  341.     for (t = tclasses->next; t!=NULL; t=t->next)
  342.     {
  343.         p = (TCnode *) t->elem;
  344.  
  345.         /* if wild card, then won't have entries in tclass, assume all_tokens */
  346.         if ( p->tok == WildCardToken )
  347.         {
  348.             p->tset = set_dup(all_tokens);
  349.             continue;
  350.         }
  351.  
  352.         lexmode(p->lexclass);    /* switch to lexclass where tokclass is defined */
  353.         p->tset = empty;
  354.  
  355.         /* instantiate all tokens/token_classes into the tset */
  356.         for (e = (p->tlist)->next; e!=NULL; e=e->next)
  357.         {
  358.             char *tokstr;
  359.             tokstr = (char *)e->elem;
  360.             if ( *tokstr == '"' ) q = (TermEntry *) hash_get(Texpr, tokstr);
  361.             else q = (TermEntry *) hash_get(Tname, tokstr);
  362.             require(q!=NULL, "ComputeTokSets: no token def");
  363.             set_orel(q->token, &p->tset);
  364.         }
  365.     }
  366.  
  367.     /* Go thru list of tokclasses again looking for tokclasses in sets */
  368. again:
  369.     something_changed = 0;
  370.     for (t = tclasses->next; t!=NULL; t=t->next)
  371.     {
  372.         set tcl;
  373.         p = (TCnode *) t->elem;
  374.         tcl = set_and(p->tset, tokclasses);
  375.         if ( !set_nil(tcl) )
  376.         {
  377.             int tk;
  378.             /* replace refs to tokclasses with the associated set of tokens */
  379.             something_changed = 1;
  380.             while ( !set_nil(tcl) )
  381.             {
  382.                 tk = set_int(tcl);        /* grab one of the tok class refs */
  383.                 set_rm(tk, tcl);
  384.                 if ( p->tok != tk )        /* tokclass ref to yourself? */
  385.                 {
  386.                     q = (TermEntry *) hash_get(Tname, TokenString(tk));
  387.                     require(q!=NULL, "#tokclass not in hash table");
  388.                     set_orin(&p->tset, q->tclass->tset);
  389.                 }
  390.                 set_rm(tk, p->tset);    /* remove ref that we replaced */
  391.             }
  392.         }
  393.         set_free(tcl);
  394.     }
  395.     if ( something_changed ) goto again;
  396. }
  397.  
  398. void
  399. DumpRemainingTokSets()
  400. {
  401.     TCnode *p;
  402.     ListNode *t;
  403.  
  404.     /* Go thru tclasses (for the last time) and dump the sets not dumped
  405.      * during code gen; yes, this is a bogus way to do this, but ComputeTokSets()
  406.      * can't dump the defs as the error file and tok file has not been created
  407.      * yet etc...
  408.      */
  409.     if ( tclasses==NULL ) return;
  410.     for (t = tclasses->next; t!=NULL; t=t->next)
  411.     {
  412.         unsigned e;
  413.         p = (TCnode *) t->elem;
  414.         if ( p->dumped ) continue;
  415.         e = DefErrSet(&(p->tset), 0, TokenString(p->tok));
  416.         p->dumped = 1;
  417.         p->setnum = e;
  418.     }
  419. }
  420.  
  421.  
  422. /* replace a subset of an error set with an error class name if a subset is found
  423.  * repeat process until no replacements made
  424.  */
  425. void
  426. #ifdef __STDC__
  427. SubstErrorClass( set *f )
  428. #else
  429. SubstErrorClass( f )
  430. set *f;
  431. #endif
  432. {
  433.     int max, done = 0;
  434.     ListNode *p;
  435.     ECnode *ec, *maxclass = NULL;
  436.     set a;
  437.     require(f!=NULL, "SubstErrorClass: NULL eset");
  438.  
  439.     if ( eclasses == NULL ) return;
  440.     while ( !done )
  441.     {
  442.         max = 0;
  443.         maxclass = NULL;
  444.         for (p=eclasses->next; p!=NULL; p=p->next)    /* chk all error classes */
  445.         {
  446.             ec = (ECnode *) p->elem;
  447.             if ( ec->setdeg > max )
  448.             {
  449.                 if ( set_sub(ec->eset, *f) || set_equ(ec->eset, *f) )
  450.                     {maxclass = ec; max=ec->setdeg;}
  451.             }
  452.         }
  453.         if ( maxclass != NULL )    /* if subset found, replace with token */
  454.         {
  455.             a = set_dif(*f, maxclass->eset);
  456.             set_orel((unsigned)maxclass->tok, &a);
  457.             set_free(*f);
  458.             *f = a;
  459.         }
  460.         else done = 1;
  461.     }
  462. }
  463.  
  464. int
  465. #ifdef __STDC__
  466. DefErrSet( set *f, int subst, char *name )
  467. #else
  468. DefErrSet( f, subst, name )
  469. set *f;
  470. int subst;            /* should be substitute error classes? */
  471. char *name;
  472. #endif
  473. {
  474.     if ( GenCC ) return DefErrSetForCC( f, subst, name );
  475.     else return DefErrSetForC( f, subst, name );
  476. }
  477.  
  478. /* Define a new error set.  WARNING...set-implementation dependent.
  479.  */
  480. int
  481. #ifdef __STDC__
  482. DefErrSetForC( set *f, int subst, char *name )
  483. #else
  484. DefErrSetForC( f, subst, name )
  485. set *f;
  486. int subst;            /* should be substitute error classes? */
  487. char *name;
  488. #endif
  489. {
  490.     unsigned *p, *endp;
  491.     int e=1;
  492.     require(!set_nil(*f), "DefErrSet: nil set to dump?");
  493.  
  494.     if ( subst ) SubstErrorClass(f);
  495.     p = f->setword;
  496.     endp = &(f->setword[f->n]);
  497.     esetnum++;
  498.     if ( name!=NULL )
  499.         fprintf(DefFile, "extern SetWordType %s_set[];\n", name);
  500.     else
  501.         fprintf(DefFile, "extern SetWordType zzerr%d[];\n", esetnum);
  502.     if ( name!=NULL ) {
  503.         fprintf(ErrFile, "SetWordType %s_set[%d] = {",
  504.                 name,
  505.                 NumWords(TokenNum-1)*sizeof(unsigned));
  506.     }
  507.     else {
  508.         fprintf(ErrFile, "SetWordType zzerr%d[%d] = {",
  509.                 esetnum,
  510.                 NumWords(TokenNum-1)*sizeof(unsigned));
  511.     }
  512.     while ( p < endp )
  513.     {
  514.         if ( e > 1 ) fprintf(ErrFile, ", ");
  515.         DumpIntAsChars(ErrFile, "0x%x", *p++);
  516.         if ( e == 3 )
  517.         {
  518.             DAWDLE;
  519.             if ( p < endp ) fprintf(ErrFile, ",");
  520.             fprintf(ErrFile, "\n\t");
  521.             e=1;
  522.         }
  523.         else e++;
  524.     }
  525.     fprintf(ErrFile, "};\n");
  526.  
  527.     return esetnum;
  528. }
  529.  
  530. /* Define a new error set.  WARNING...set-implementation dependent;
  531.  * Only used when -CC on.
  532.  */
  533. int
  534. #ifdef __STDC__
  535. DefErrSetForCC( set *f, int subst, char *name )
  536. #else
  537. DefErrSetForCC( f, subst, name )
  538. set *f;
  539. int subst;            /* should be substitute error classes? */
  540. char *name;
  541. #endif
  542. {
  543.     unsigned *p, *endp;
  544.     int e=1;
  545.     require(!set_nil(*f), "DefErrSet: nil set to dump?");
  546.  
  547.     if ( subst ) SubstErrorClass(f);
  548.     p = f->setword;
  549.     endp = &(f->setword[f->n]);
  550.     esetnum++;
  551.  
  552.     if ( name!=NULL ) {
  553.         fprintf(Parser_h, "\tstatic SetWordType %s_set[%d];\n", name,
  554.                 NumWords(TokenNum-1)*sizeof(unsigned));
  555.         fprintf(Parser_c, "SetWordType %s::%s_set[%d] = {",
  556.                 CurrentClassName,
  557.                 name,
  558.                 NumWords(TokenNum-1)*sizeof(unsigned));
  559.     }
  560.     else {
  561.         fprintf(Parser_c, "SetWordType %s::err%d[%d] = {",
  562.                 CurrentClassName,
  563.                 esetnum,
  564.                 NumWords(TokenNum-1)*sizeof(unsigned));
  565.         fprintf(Parser_h, "\tstatic SetWordType err%d[%d];\n", esetnum,
  566.                 NumWords(TokenNum-1)*sizeof(unsigned));
  567.     }
  568.  
  569.     while ( p < endp )
  570.     {
  571.         if ( e > 1 ) fprintf(Parser_c, ", ");
  572.         DumpIntAsChars(Parser_c, "0x%x", *p++);
  573.         if ( e == 3 )
  574.         {
  575.             if ( p < endp ) fprintf(Parser_c, ",");
  576.             fprintf(Parser_c, "\n\t");
  577.             e=1;
  578.         }
  579.         else e++;
  580.     }
  581.     fprintf(Parser_c, "};\n");
  582.  
  583.     return esetnum;
  584. }
  585.  
  586. void
  587. #ifdef __STDC__
  588. GenParser_c_Hdr(void)
  589. #else
  590. GenParser_c_Hdr()
  591. #endif
  592. {
  593.     int i,j;
  594.  
  595.     fprintf(Parser_c, "/*\n");
  596.     fprintf(Parser_c, " * %s: P a r s e r  S u p p o r t\n", CurrentClassName);
  597.     fprintf(Parser_c, " *\n");
  598.     fprintf(Parser_c, " * Generated from:");
  599.     for (i=0; i<NumFiles; i++) fprintf(Parser_c, " %s", FileStr[i]);
  600.     fprintf(Parser_c, "\n");
  601.     fprintf(Parser_c, " *\n");
  602.     fprintf(Parser_c, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  603.     fprintf(Parser_c, " * Purdue University Electrical Engineering\n");
  604.     fprintf(Parser_c, " * With AHPCRC, University of Minnesota\n");
  605.     fprintf(Parser_c, " * ANTLR Version %s\n", Version);
  606.     fprintf(Parser_c, " */\n\n");
  607.     fprintf(Parser_c, "#include <stdio.h>\n");
  608.     fprintf(Parser_c, "#define ANTLR_VERSION    %s\n", VersionDef);
  609.     if ( UserTokenDefsFile != NULL )
  610.        fprintf(Parser_c, "#include %s\n", UserTokenDefsFile);
  611.     else
  612.        fprintf(Parser_c, "#include \"%s\"\n", DefFileName);
  613.  
  614.     fprintf(Parser_c, "#include \"%s.h\"\n", CurrentClassName);
  615.  
  616.     /* Dump a Parser::tokens for each automaton */
  617.     fprintf(Parser_c, "\nANTLRChar *%s::_token_tbl[]={\n", CurrentClassName);
  618.     fprintf(Parser_c, "\t/* 00 */\t\"Invalid\"");
  619.  
  620.     for (i=1; i<TokenNum-1; i++)
  621.     {
  622.         DAWDLE;
  623.         if ( i == EpToken ) continue;
  624.         /* remapped to invalid token? */
  625.         if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )
  626.         {
  627.             fprintf(Parser_c, ",\n\t/* %02d */\t\"invalid\"", i);
  628.             continue;
  629.         }
  630.         if ( TokenString(i) != NULL )
  631.             fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));
  632.         else
  633.         {
  634.             /* look in all lexclasses for the reg expr */
  635.             for (j=0; j<NumLexClasses; j++)
  636.             {
  637.                 lexmode(j);
  638.                 if ( ExprString(i) != NULL )
  639.                 {
  640.                     fprintf(Parser_c, ",\n\t/* %02d */\t", i);
  641.                     dumpExpr(Parser_c, ExprString(i));
  642.                     break;
  643.                 }
  644.             }
  645.             if ( j>=NumLexClasses )
  646.             {
  647.                 if ( UserDefdTokens )
  648.                 {
  649.                     fprintf(Parser_c, ",\n\t/* %02d */\t\"\"", i);
  650.                 }
  651.                 else
  652.                     fatal_internal(eMsgd("No label or expr for token %d",i));
  653.             }
  654.         }
  655.     }
  656.     fprintf(Parser_c, "\n};\n");
  657.  
  658.     /* Build constructors */
  659.     fprintf(Parser_c, "\n%s::", CurrentClassName);
  660.     fprintf(Parser_c,    "%s(ANTLRTokenBuffer *input) : ANTLRParser(input,%d,%d,%d,%d)\n",
  661.                         CurrentClassName,
  662.                         OutputLL_k,
  663.                         FoundGuessBlk,
  664.                         DemandLookahead,
  665.                         NumWords(TokenNum-1)*sizeof(unsigned));
  666.     fprintf(Parser_c, "{\n");
  667.     fprintf(Parser_c, "\ttoken_tbl = _token_tbl;\n");
  668.     fprintf(Parser_c, "}\n\n");
  669. }
  670.  
  671. void
  672. #ifdef __STDC__
  673. GenParser_h_Hdr(void)
  674. #else
  675. GenParser_h_Hdr()
  676. #endif
  677. {
  678.     int i;
  679.  
  680.     fprintf(Parser_h, "/*\n");
  681.     fprintf(Parser_h, " * %s: P a r s e r  H e a d e r \n", CurrentClassName);
  682.     fprintf(Parser_h, " *\n");
  683.     fprintf(Parser_h, " * Generated from:");
  684.     for (i=0; i<NumFiles; i++) fprintf(Parser_h, " %s", FileStr[i]);
  685.     fprintf(Parser_h, "\n");
  686.     fprintf(Parser_h, " *\n");
  687.     fprintf(Parser_h, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  688.     fprintf(Parser_h, " * Purdue University Electrical Engineering\n");
  689.     fprintf(Parser_h, " * With AHPCRC, University of Minnesota\n");
  690.     fprintf(Parser_h, " * ANTLR Version %s\n", Version);
  691.     fprintf(Parser_h, " */\n\n");
  692.     fprintf(Parser_h, "#ifndef %s_h\n", CurrentClassName);
  693.     fprintf(Parser_h, "#define %s_h\n", CurrentClassName);
  694.     if ( GenAST ) fprintf(Parser_h, "class ASTBase;\n");
  695.     fprintf(Parser_h, "#include \"%s\"\n\n", APARSER_H);
  696.  
  697.     if ( HdrAction != NULL ) dumpAction( HdrAction, Parser_h, 0, -1, 0, 1);
  698.     
  699.     fprintf(Parser_h, "class %s : public ANTLRParser {\n", CurrentClassName);
  700.     fprintf(Parser_h, "protected:\n");
  701.     fprintf(Parser_h, "\tstatic ANTLRChar *_token_tbl[];\n");
  702.     fprintf(Parser_h, "private:\n");
  703. }
  704.  
  705. /* Currently, this is only used in !GenCC mode */
  706. void
  707. #ifdef __STDC__
  708. GenErrHdr( void )
  709. #else
  710. GenErrHdr( )
  711. #endif
  712. {
  713.     int i, j;
  714.  
  715.     fprintf(ErrFile, "/*\n");
  716.     fprintf(ErrFile, " * A n t l r  S e t s / E r r o r  F i l e  H e a d e r\n");
  717.     fprintf(ErrFile, " *\n");
  718.     fprintf(ErrFile, " * Generated from:");
  719.     for (i=0; i<NumFiles; i++) fprintf(ErrFile, " %s", FileStr[i]);
  720.     fprintf(ErrFile, "\n");
  721.     fprintf(ErrFile, " *\n");
  722.     fprintf(ErrFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  723.     fprintf(ErrFile, " * Purdue University Electrical Engineering\n");
  724.     fprintf(ErrFile, " * With AHPCRC, University of Minnesota\n");
  725.     fprintf(ErrFile, " * ANTLR Version %s\n", Version);
  726.     fprintf(ErrFile, " */\n\n");
  727.     fprintf(ErrFile, "#include <stdio.h>\n");
  728.     fprintf(ErrFile, "#define ANTLR_VERSION    %s\n", VersionDef);
  729.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  730.         fprintf(ErrFile, "#define %s %s\n", DefaultParserName, ParserName);
  731.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  732.         fprintf(ErrFile, "#include \"%s\"\n", RemapFileName);
  733.     if ( HdrAction != NULL ) dumpAction( HdrAction, ErrFile, 0, -1, 0, 1 );
  734.     if ( FoundGuessBlk )
  735.     {
  736.         fprintf(ErrFile, "#define ZZCAN_GUESS\n");
  737.         fprintf(ErrFile, "#include <setjmp.h>\n");
  738.     }
  739.  
  740.     if ( OutputLL_k > 1 ) fprintf(ErrFile, "#define LL_K %d\n", OutputLL_k);
  741. #ifdef DUM
  742.     if ( LexGen ) fprintf(ErrFile, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));
  743. #endif
  744.     fprintf(ErrFile, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));
  745.     if ( DemandLookahead ) fprintf(ErrFile, "#define DEMAND_LOOK\n");
  746.     fprintf(ErrFile, "#include \"antlr.h\"\n");
  747.     if ( GenAST ) fprintf(ErrFile, "#include \"ast.h\"\n");
  748.             
  749.     if ( UserDefdTokens ) fprintf(ErrFile, "#include %s\n", UserTokenDefsFile);
  750.     /* still need this one as it has the func prototypes */
  751.     fprintf(ErrFile, "#include \"%s\"\n", DefFileName);
  752.     fprintf(ErrFile, "#include \"dlgdef.h\"\n");
  753.     fprintf(ErrFile, "#include \"err.h\"\n\n");
  754.  
  755.     /* Dump a zztokens for each automaton */
  756.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  757.     {
  758.         fprintf(ErrFile, "ANTLRChar *%s_zztokens[%d]={\n", ParserName, TokenNum-1);
  759.     }
  760.     else
  761.     {
  762.         fprintf(ErrFile, "ANTLRChar *zztokens[%d]={\n", TokenNum-1);
  763.     }
  764.     fprintf(ErrFile, "\t/* 00 */\t\"Invalid\"");
  765.     for (i=1; i<TokenNum-1; i++)
  766.     {
  767.         DAWDLE;
  768.         if ( i == EpToken ) continue;
  769.         /* remapped to invalid token? */
  770.         if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )
  771.         {
  772.             fprintf(ErrFile, ",\n\t/* %02d */\t\"invalid\"", i);
  773.             continue;
  774.         }
  775.         if ( TokenString(i) != NULL )
  776.             fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));
  777.         else
  778.         {
  779.             /* look in all lexclasses for the reg expr */
  780.             for (j=0; j<NumLexClasses; j++)
  781.             {
  782.                 lexmode(j);
  783.                 if ( ExprString(i) != NULL )
  784.                 {
  785.                     fprintf(ErrFile, ",\n\t/* %02d */\t", i);
  786.                     dumpExpr(ErrFile, ExprString(i));
  787.                     break;
  788.                 }
  789.             }
  790.             if ( j>=NumLexClasses )
  791.             {
  792.                 if ( UserDefdTokens )
  793.                 {
  794.                     fprintf(ErrFile, ",\n\t/* %02d */\t\"\"", i);
  795.                 }
  796.                 else
  797.                     fatal_internal(eMsgd("No label or expr for token %d",i));
  798.             }
  799.         }
  800.     }
  801.     fprintf(ErrFile, "\n};\n");
  802. }
  803.  
  804. void
  805. #ifdef __STDC__
  806. dumpExpr( FILE *f, char *e )
  807. #else
  808. dumpExpr( f, e )
  809. FILE *f;
  810. char *e;
  811. #endif
  812. {
  813.     while ( *e!='\0' )
  814.     {
  815.         if ( *e=='\\' && *(e+1)=='\\' )
  816.             {putc('\\', f); putc('\\', f); e+=2;}
  817.         else if ( *e=='\\' && *(e+1)=='"' )
  818.             {putc('\\', f); putc('"', f); e+=2;}
  819.         else if ( *e=='\\' ) {putc('\\', f); putc('\\', f); e++;}
  820.         else {putc(*e, f); e++;}
  821.     }
  822. }
  823.